import { checkLoadEleCompelete, sleep, triggerCheckbox, selectUser, scrollToVisible, waitForSome } from '../../../utils';
import tree from './privilege-tree.json';
import { getOriginWindow } from '../../../utils';

/**
 * @typedef {'admin'|'super'|'member'} ViewType
 * @typedef {{name: string, code: string, view: ViewType[], children: IPrivilegeNode[]}} IPrivilegeNode
*/

/**
 * 
 * @param {string} list 
 * @param {boolean} check 
 */
export async function modPrivilge(list, check) {
    await waitForSome(() => cy.$$('.8fb83725b612').length > 0)
    const container = cy.$$('.8fb83725b612');
    for(let item of list) {
        let node = container.find(`*[code=${item}]`);
        let checkboxInput = node.find('.ant-checkbox-input').eq(0);
        // kpd-checkbox
        if(node.find('.kpd-checkbox').length > 0) { // 当前没有check
            if(check) {
                checkboxInput.trigger('click'); 
                await waitForSome(() => container.find(`*[code=${item}]`).find('.kpd-checkbox').length === 0);
            }
        } else {
            if(!check) {
                checkboxInput.trigger('click');
                await waitForSome(() => container.find(`*[code=${item}]`).find('.kpd-checkbox').length === 1);
            }
        }
    }
}

/**
 * @returns {{performance: IPrivilegeNode[], data: IPrivilegeNode[]}[]}
 */
function getTree() {
    return JSON.parse(JSON.stringify(tree));
}

/**
 * 
 * @param {IPrivilegeNode[]} nodes 
 * @param {ViewType[]} types 
 * @returns {IPrivilegeNode[]}
 */
function cutNode(nodes, types) {
    return nodes.map(node => {
        for(let type of types) {
            // debugger
            if(node.view.indexOf(type) !== -1) {
                if(Array.isArray(node.children)) {
                    node.children = cutNode(node.children, types);
                }
                
                return node;
            }
        }
        return null;
    }).filter(node => node !== null);
}
/**
 * 
 * @param {IPrivilegeNode[]} nodes
 * @param {IPrivilegeNode|null} parent 
 */
function createNodeRelation(nodes, parent) {
    for(let node of nodes) {
        node.parent = parent;
        if(Array.isArray(node.children) && node.children.length > 0) {
            createNodeRelation(node.children, node);
        }
    }
}
/**
 * 
 * @param {string} privilege 
 * @param {IPrivilegeNode[]} nodes
 * @returns {IPrivilegeNode|null};
 */
function findNode(privilege, nodes) {
    for(let node of nodes) {
        if(node.code === privilege) {
            return node;
        }
        if(Array.isArray(node.children) && node.children.length > 0) {
            let find = findNode(privilege, node.children);
            if(find !== null) {
                return find;
            }
        }
    }
    return null;
}
/**
 * 
 * @param {IPrivilegeNode|{parent: IPrivilegeNode}} node 
 * @returns {string[]}
 */
function collectParent(node) {
    /**
     * @type {string}
     */
    let result = [];
    
    const travelParent = (_node) => {
        result.push(_node.code);
        if(_node.parent !== null) {
            travelParent(_node.parent);
        }
    }
    travelParent(node);
    return result;
}
/**
 * @param {IPrivilegeNode|{parent: IPrivilegeNode}} node 
 * 
 * @returns {string[]}
 */
function collectChildren(node) {
    /**
     * @type {string}
     */
     let result = [];
    const travelChildren = (_node) => {
        result.push(_node.code);
        if(Array.isArray(_node.children) && _node.children.length > 0) {
            for(let item of _node.children) {
                travelChildren(item);
            }
        }
    }
    travelChildren(node);
    return result;
}
/**
 * @param {ViewType} type 
 * @returns {(IPrivilegeNode&{parent: null|IPrivilegeNode})[]}
 */
export function filterPrivilegeTree(type) {
    let tree = getTree();
    /**
     * @type {(IPrivilegeNode&{parent: null|IPrivilegeNode})[]}
     */
    let nodes = [];
    for(let item of tree) {
        item.performance = cutNode(item.performance, type);
        console.log(item)
        createNodeRelation(item.performance, null);
        item.data = cutNode(item.data, type);
        createNodeRelation(item.data, null);
        nodes.push(...item.performance, ...item.data);
    }
    return nodes;
}
/**
 * 
 * @param {ViewType} type 
 * @param {string[]} privileges 
 * @param {'add'|'remove'} operate 
 */
export function updatenewPrivilge(type, privileges, operate) {
    /**
     * @type {(IPrivilegeNode&{parent: null|IPrivilegeNode})[]}
     */
    let nodes = filterPrivilegeTree(type)
    /**
     * @type {string[]}
     */
    let result = [];

    for(let privilege of privileges) {
        let find = findNode(privilege, nodes);
        if(find === null) continue;
        /**
         * @type {string[]}
         */
        let values = [];
        if(operate === 'add') {
            values = collectParent(find);
        } else {
            values = collectChildren(find);
        }
        result.push(...values);
    }
    return result;
}

/**
 * 
 * @returns {number}
 */
export function getRoleIdByUrl() {
    let win = getOriginWindow();
    let paths = win.location.pathname.split('/');
    return Number(paths[3]);
}
/**
 * 
 * @param {(IPrivilegeNode&{parent: null|IPrivilegeNode})[]} nodes 
 */
function collectCodesFromNodes(nodes) {
    /**
     * @type {string[]}
     */
    const result = [];
    /**
     * @type {(nodes: (IPrivilegeNode&{parent: null|IPrivilegeNode})[]) => void}
     */
    const _collect = (_nodes) => {
        for(let _node of _nodes) {
            result.push(_node.code);
            if(Array.isArray(_node.children)) {
                _collect(_node.children);
            }
        }
    }
    return result;
}
/**
 * 
 * @param {ViewType} type 
 * @returns {string[]}
 */
export function getAllViewTypePrivilges(type) {
    let nodes = filterPrivilegeTree(type);
    return collectCodesFromNodes(nodes);
}
